package org.meichao.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * 由其他RedisConfig继承,可实现多Redis缓存
 *  参考DefaultRedisConfig，在yml文件中配置基础(index,host等)，然后调用自定义工厂生成连接池
 */
@Configuration
public class RedisConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
    @Scope(value = "prototype")
    public GenericObjectPoolConfig redisPool(){
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        return genericObjectPoolConfig;
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.redis.local")
    public RedisStandaloneConfiguration local(){
        return new RedisStandaloneConfiguration();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.redis.sys")
    public RedisStandaloneConfiguration sys(){
        return new RedisStandaloneConfiguration();
    }

    @Bean
    @Primary
    public LettuceConnectionFactory sysStringRedisTemFactory(){
        GenericObjectPoolConfig config = redisPool();
        LettuceClientConfiguration lettuceConnectionFactory = LettucePoolingClientConfiguration.builder()
                .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
        return new LettuceConnectionFactory(local(), lettuceConnectionFactory);
    }

    @Bean
    public LettuceConnectionFactory readStringRedisTemFactory(){
        GenericObjectPoolConfig config = redisPool();
        LettuceClientConfiguration lettuceConnectionFactory = LettucePoolingClientConfiguration.builder()
                .poolConfig(config).commandTimeout(Duration.ofMillis(config.getMaxWaitMillis())).build();
        return new LettuceConnectionFactory(sys(), lettuceConnectionFactory);
    }

    @Bean
    @Primary
    public StringRedisTemplate stringRedisTemplate(){
        StringRedisTemplate template = getRedisTemplate();
        template.setConnectionFactory(sysStringRedisTemFactory());
        return template;
    }

    @Bean(name = "readRedisTemplate")
    public StringRedisTemplate readStringRedisTemplate(){
        StringRedisTemplate template = getRedisTemplate();
        template.setConnectionFactory(readStringRedisTemFactory());
        return template;
    }

    private StringRedisTemplate getRedisTemplate(){
        StringRedisTemplate template = new StringRedisTemplate();
        template.setValueSerializer(new GenericFastJsonRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        return template;
    }

}
